package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"coupons/config"
	"coupons/repo"
	"coupons/router"
	"coupons/service"

	"github.com/gin-gonic/gin"
)

func main() {
	// 加载配置
	cfg, err := config.LoadConfig(".env")
	if err != nil {
		log.Fatal("加载配置失败:", err)
	}

	// 初始化数据库
	db, err := config.InitDatabase()
	if err != nil {
		log.Fatal("数据库连接失败:", err)
	}

	// 初始化Redis
	rdb, err := config.InitRedis()
	if err != nil {
		log.Fatal("Redis连接失败:", err)
	}
	defer rdb.Close()

	// 创建repo层实例
	voucherRepo := repo.NewVoucherRepo(db)
	orderRepo := repo.NewOrderRepo(db)

	// 创建WebSocket Hub
	wsHub := service.NewHub(db)
	go service.RunHub(wsHub)

	// 创建秒杀服务
	seckillService := service.NewSeckillService(voucherRepo, orderRepo, rdb, wsHub)

	// 启动定时任务
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// 启动优惠券扫描任务
	go seckillService.StartVoucherScanTask(ctx)

	// 设置路由
	engine := router.SetupRouter(seckillService, wsHub)

	// 创建HTTP服务器
	srv := &http.Server{
		Addr:    fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port),
		Handler: engine,
	}

	// 启动服务器
	go func() {
		log.Printf("服务器启动在 %s", srv.Addr)
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatal("服务器启动失败:", err)
		}
	}()

	// 等待中断信号优雅关闭
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	log.Println("正在关闭服务器...")

	// 设置5秒超时
	ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := srv.Shutdown(ctx); err != nil {
		log.Fatal("服务器强制关闭:", err)
	}

	log.Println("服务器已关闭")
}

// init 初始化Gin模式
func init() {
	// 默认设置为发布模式
	gin.SetMode(gin.ReleaseMode)
}
